home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume3 / pcmail / part04 < prev    next >
Encoding:
Text File  |  1989-02-03  |  57.5 KB  |  2,038 lines

  1. Path: xanth!mcnc!uvaarpa!umd5!ames!necntc!ncoast!allbery
  2. From: wswietse@eutrc3.UUCP (Wietse Venema)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i005: uucp mail for pc's (4 of 8)
  5. Message-ID: <213@eutrc3.UUCP>
  6. Date: 20 Apr 88 16:47:52 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: wswietse@eutrc3.UUCP (Wietse Venema)
  9. Organization: Tech. Univ. Eindhoven, Neth.
  10. Lines: 2025
  11. Approved: allbery@ncoast.UUCP
  12.  
  13. comp.sources.misc: Volume 3, Issue 5
  14. Submitted-By: "Wietse Venema" <wswietse@eutrc3.UUCP>
  15. Archive-Name: pcmail/Part4
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 4 (of 8)."
  24. # Contents:  Watchit cico.c connect.c email.c gp.h gpres.c ktrans.c
  25. #   makefile.msc rmail.c startup.c
  26. # Wrapped by wietse@eutwc1 on Wed Apr 20 16:45:16 1988
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f Watchit -a "${1}" != "-c" ; then 
  29.   echo shar: Will not over-write existing file \"Watchit\"
  30. else
  31. echo shar: Extracting \"Watchit\" \(649 characters\)
  32. sed "s/^X//" >Watchit <<'END_OF_Watchit'
  33. XMicrosoft decided to change the order of function arguments of
  34. Xthe rename() function. Check the source against the documentation
  35. Xof your compiler.
  36. X
  37. XSome functions are used in all programs. Therefore, everything has to 
  38. Xbe compiled with the same memory model.
  39. X
  40. XSince the assembly-language serial port driver assumes a small
  41. Xmemory model, all programs have to be compiled with the small memory
  42. Xmodel.
  43. X
  44. XThe MAILDIR, EDITOR environment variables should hold absolute path
  45. Xnames. On MS-DOS systems (floppies!) it is a good idea to include
  46. Xthe drive name as well.
  47. X
  48. XOn some MS-DOS systems the directory listing (file command) does
  49. Xnot show the ".." entry.
  50. END_OF_Watchit
  51. if test 649 -ne `wc -c <Watchit`; then
  52.     echo shar: \"Watchit\" unpacked with wrong size!
  53. fi
  54. # end of overwriting check
  55. fi
  56. if test -f cico.c -a "${1}" != "-c" ; then 
  57.   echo shar: Will not over-write existing file \"cico.c\"
  58. else
  59. echo shar: Extracting \"cico.c\" \(4984 characters\)
  60. sed "s/^X//" >cico.c <<'END_OF_cico.c'
  61. X/*++
  62. X/* NAME
  63. X/*      cico 1
  64. X/* SUMMARY
  65. X/*      uucp file transfer
  66. X/* PROJECT
  67. X/*      pc-mail
  68. X/* PACKAGE
  69. X/*      cico
  70. X/* SYNOPSIS
  71. X/*      cico -p password [-d debuglevel]
  72. X/* DESCRIPTION
  73. X/*      cico is a program that connects to a real unix host
  74. X/*      for exchange of spool files. It is a simplified
  75. X/*    version of the unix uucico (copy-in-copy-out) program.
  76. X/*
  77. X/*    Options:
  78. X/* .TP
  79. X/*    -p password
  80. X/*    The password that cico will use when logging in on the
  81. X/*    unix host.
  82. X/* .TP
  83. X/*    -d debuglevel
  84. X/*      Set the debugging level. It makes both the local cico
  85. X/*      and the remote uucico more verbose. Default debugging
  86. X/*    level is 0.
  87. X/* FILES
  88. X/*      cico manipulates various files in the spool directory.
  89. X/*    See path(5) for the implementation of the message data base.
  90. X/*
  91. X/*      LOGFILE         transaction logging
  92. X/*    s00000        communications parameters
  93. X/* SEE ALSO
  94. X/*      comm(5)        communications parameters
  95. X/*    status(5)    error returns
  96. X/* DIAGNOSTICS
  97. X/*      The program terminates with a non-zero exit status if there
  98. X/*      were problems. The error status codes can be translated
  99. X/*    to meaningful messages (see status(5)).
  100. X/*      More technical messages are written to the logfile.
  101. X/* BUGS
  102. X/*    cico only supports the functions needed for exchange of
  103. X/*    electronic mail. Every incoming data file is treated as
  104. X/*    if it were a mail message for the user of the pc.
  105. X/* AUTHOR(S)
  106. X/*      W.Z. Venema
  107. X/*      Eindhoven University of Technology
  108. X/*      Department of Mathematics and Computer Science
  109. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  110. X/* CREATION DATE
  111. X/*      Sat Mar 28 19:58:06 GMT+1:00 1987
  112. X/* LAST MODIFICATION
  113. X/*    Wed Apr  6 00:18:29 MET 1988
  114. X/* VERSION/RELEASE
  115. X/*    1.6
  116. X/*--*/
  117. X
  118. X#include <setjmp.h>
  119. X#include "defs.h"
  120. X#include "logs.h"
  121. X#include "params.h"
  122. X#include "comm.h"
  123. X#include "status.h"
  124. X#include "path.h"
  125. X
  126. Xpublic int *systrap;                            /* panic button */
  127. Xpublic int dflag = 0;                           /* debug flag */
  128. X#ifdef    unix
  129. X    public int Debug = 0;            /* UUCP compatibility */
  130. X#endif
  131. X
  132. Xhidden void parse_args(),sanity();              /* forward declarations */
  133. X
  134. X/* main program - parse command line options and pull the ropes */
  135. X
  136. Xmain(argc,argv)
  137. Xint argc;
  138. Xchar **argv;
  139. X{
  140. X    register int status;                        /* most recent error code */
  141. X    jmp_buf mainbuf;                            /* catch-all */
  142. X
  143. X    parse_args(argc,argv);                      /* process cmd arguments */
  144. X
  145. X    sanity();                                   /* check systems parameters */
  146. X
  147. X    if (setjmp(systrap = mainbuf))              /* safety net in case of */
  148. X    exit(E_CONFUSED);                       /* too many long jumps */
  149. X
  150. X    xopen();                                    /* init comm. line */
  151. X    if ((status = connect()) == 0               /* login on remote system */
  152. X    && (status = startproto()) == 0) {          /* start comm. protocol */
  153. X    status = switcher(MASTER);              /* use the protocol */
  154. X    endproto();                             /* terminate the protocol */
  155. X    }                                           /* (ignore errors) */
  156. X    disconnect();                               /* as it says */
  157. X    xclose();                                   /* close comm. line */
  158. X
  159. X    exit(status);
  160. X    /* NOTREACHED */
  161. X}
  162. X
  163. X/* parse_args - take care of command-line arguments */
  164. X
  165. Xhidden void parse_args(argc,argv)
  166. Xint argc;
  167. Xchar **argv;
  168. X{
  169. X    while (--argc && *++argv && **argv == '-') {
  170. X    switch (*++*argv) {
  171. X    case 'p':
  172. X        if (--argc == 0)
  173. X        usage("missing password argument");
  174. X        password = *++argv;
  175. X        break;
  176. X    case 'd':
  177. X        if (--argc == 0)
  178. X        usage("missing debugging level argument");
  179. X        sscanf(*++argv,"%d",&dflag);
  180. X#ifdef    unix
  181. X        Debug = 
  182. X#endif
  183. X        dflag = ((dflag < 0 ? 0 : dflag) > 10 ? 10 : dflag);
  184. X        break;
  185. X    default:
  186. X        usage(strcons("invalid option: -%s",*argv));
  187. X        break;
  188. X    }
  189. X    }
  190. X    if (argc > 0)
  191. X    usage(strcons("unexpected argument: %s",*argv));
  192. X}
  193. X
  194. X/* sanity - some preliminary work; mainly checks on sanity */
  195. X
  196. Xhidden void sanity()
  197. X{
  198. X    register int status;
  199. X    register Info *ip;
  200. X
  201. X    if (status = pathinit())                            /* check environment */
  202. X    exit(status);                                   /* bad environment */
  203. X
  204. X    if (status = open_log())                            /* check the logfile */
  205. X    exit(status);                                   /* cannot write */
  206. X
  207. X    for (ip = comm = getparams(); ip->ident; ip++) {    /* check param. file */
  208. X    if (ip->strval == 0 || ip->strval[0] == '\0')
  209. X        exit(E_BADSETUP);                           /* incomplete setup */
  210. X    debug(6)("%s %s\n",ip->ident,ip->strval ? ip->strval : "");
  211. X    }
  212. X    if (password == 0 || *password == 0) 
  213. X    usage("no password specified");                 /* no password */
  214. X
  215. X    strcpy(rmthost,ip[P_HOST].strval);            /* remote host name */
  216. X}
  217. X
  218. X/* usage - print error message and usage string */
  219. X
  220. Xusage(str)
  221. Xchar *str;
  222. X{
  223. X    fprintf(stderr,"%s\nusage: cico -p password [-d debuglevel]\n",str);
  224. X    exit(2);
  225. X}
  226. END_OF_cico.c
  227. if test 4984 -ne `wc -c <cico.c`; then
  228.     echo shar: \"cico.c\" unpacked with wrong size!
  229. fi
  230. # end of overwriting check
  231. fi
  232. if test -f connect.c -a "${1}" != "-c" ; then 
  233.   echo shar: Will not over-write existing file \"connect.c\"
  234. else
  235. echo shar: Extracting \"connect.c\" \(5702 characters\)
  236. sed "s/^X//" >connect.c <<'END_OF_connect.c'
  237. X/*++
  238. X/* NAME
  239. X/*      connect 3
  240. X/* SUMMARY
  241. X/*      pre- and post protocol host access
  242. X/* PROJECT
  243. X/*      pc-mail
  244. X/* PACKAGE
  245. X/*      cico
  246. X/* SYNOPSIS
  247. X/*      int connect()
  248. X/*
  249. X/*      int disconnect()
  250. X/* DESCRIPTION
  251. X/*      connect() tries to make a connection to the remote host
  252. X/*      and to log on, using the dial-up script and login-name 
  253. X/*    entries in the communications parameter file, and the password
  254. X/*    provided as command-line parameter to the cico program. 
  255. X/*    A simple send-expect script facility is used (no retries 
  256. X/*    or delays). After the dial-up script has completed the program 
  257. X/*    proceeds by expecting the login: prompt and does the final login.
  258. X/*
  259. X/*      disconnect() tries to break a connection, using the disconnect
  260. X/*      entry in the communications parameter file. Unlike connect() 
  261. X/*    this function is not driven by a send-expect script.
  262. X/*
  263. X/*    The following escape sequences are recognized in send or expect
  264. X/*    strings:
  265. X/*
  266. X/* .nf
  267. X/*    \\b    backspace
  268. X/*    \\r    carriage return
  269. X/*    \\n    newline
  270. X/*    \\t    tab
  271. X/*    \\s    space
  272. X/*    \\f    form feed
  273. X/*    \\nnn    octal character value
  274. X/*    \\\\    a real backslash
  275. X/* FUNCTIONS AND MACROS
  276. X/*      xwrite(), xgetc(), trap(), debug(4)(), log()
  277. X/* FILES
  278. X/*      $MAILDIR/s00000        communications parameter file
  279. X/*    $MAILDIR/LOGFILE    system logfile
  280. X/* SEE ALSO
  281. X/*      params(5)       communications parameter file entries
  282. X/* DIAGNOSTICS
  283. X/*      connect() returns a status E_BADSETUP if the systems parameter
  284. X/*    file contains bad data, and E_NOLINE if the login script fails.
  285. X/* AUTHOR(S)
  286. X/*      W.Z. Venema
  287. X/*      Eindhoven University of Technology
  288. X/*      Department of Mathematics and Computer Science
  289. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  290. X/* CREATION DATE
  291. X/*      Fri Mar 27 17:11:12 GMT+1:00 1987
  292. X/* LAST MODIFICATION
  293. X/*    Wed Apr  6 00:19:26 MET 1988
  294. X/* VERSION/RELEASE
  295. X/*    1.4
  296. X/*--*/
  297. X
  298. X#include <setjmp.h>
  299. X#include <ctype.h>
  300. X#include "defs.h"
  301. X#include "params.h"
  302. X#include "status.h"
  303. X#include "comm.h"
  304. X#include "logs.h"
  305. X#include "sysdep.h"
  306. X
  307. Xhidden char *blnk = " \t";            /* send/expect separators */
  308. X
  309. X/* forward declarations */
  310. X
  311. Xhidden void conn_send();
  312. Xhidden void conn_xpct();
  313. Xhidden char *escape();
  314. X
  315. X/* connect - connect to remote system; simple script processing (no retries) */
  316. X
  317. Xpublic int connect()
  318. X{
  319. X    int *savetrap = systrap;                    /* save exception handler */
  320. X    jmp_buf mytrap;                /* our exception handler */
  321. X    int retval;                    /* completion code */
  322. X    register char *cp;
  323. X
  324. X    /* set up exception handler */
  325. X
  326. X    if (retval = setjmp(systrap = mytrap)) {    /* get here if expect fails */
  327. X    systrap = savetrap;            /* it just happened */
  328. X    return(retval);
  329. X    }
  330. X
  331. X    /* optional dial-up sequence */
  332. X
  333. X    for (cp = strtok(DIAL_SEQUENCE,blnk); cp; cp = strtok((char *)0,blnk)) {
  334. X    conn_send(escape(cp));
  335. X    if (cp = strtok((char *)0,blnk))
  336. X        conn_xpct(escape(cp));
  337. X    }
  338. X
  339. X    /* mandatory login sequence */
  340. X
  341. X    conn_xpct("ogin:");
  342. X    conn_send(strcons("%s\r",LOGIN_NAME));
  343. X    conn_xpct("ssword:");
  344. X    conn_send(strcons("%s\r",password));
  345. X
  346. X    /* restore exception handler */
  347. X
  348. X    systrap = savetrap;                         /* get here if expect wins */
  349. X    return(0);                    /* say no problems... */
  350. X}
  351. X
  352. X/* disconnect - disconnect line */
  353. X
  354. Xpublic int disconnect()
  355. X{
  356. X    conn_send(escape(DISC_SEQUENCE));        /* send disconnect sequence */
  357. X    return(0);                    /* always succeeds... */
  358. X}
  359. X
  360. X/* conn_send - quick-and-dirty output function */
  361. X
  362. Xhidden void conn_send(s)
  363. Xregister char *s;
  364. X{
  365. X    sleep(1);
  366. X
  367. X    if (*s) {
  368. X    debug(4)("Sending: %S\n",s);
  369. X    while (*s) {
  370. X        delay();
  371. X        xwrite(ttfd,s++,1);
  372. X    }
  373. X    }
  374. X}
  375. X
  376. X/* conn_xpct - primitive pattern matching without meta characters */
  377. X
  378. Xhidden void conn_xpct(s)
  379. Xchar *s;
  380. X{
  381. X    register int c,i;
  382. X    register int n = strlen(s);
  383. X
  384. X    /*
  385. X    * Keep listening until we time out or until we receive the 
  386. X    * expected string. Make sure that we do not overrun our buffer.
  387. X    * Parity bits are ignored.
  388. X    */
  389. X
  390. X    if (n) {
  391. X    debug(4)("Expecting: %S\nReceiving: ",s);
  392. X
  393. X    if (n > MSGBUF) n = MSGBUF;
  394. X
  395. X    for (i = 0; (c = xgetc()) != EOF; ) {
  396. X        msgin[i++] = (c &= 0177);
  397. X        debug(4)("%C",c);
  398. X        if (i >= n && strncmp(s,&msgin[i-n],n) == 0) {
  399. X        debug(4)(" ok!\n");
  400. X        return;
  401. X        } else if (i >= MSGBUF) {
  402. X        strncpy(msgin,&msgin[i-(n-1)],n-1);
  403. X        i = n-1;
  404. X        }
  405. X    }
  406. X    debug(4)(" failed!\n");
  407. X    trap(E_NOLINE,"LOGIN FAILED (at \"%S\")",s);
  408. X    }
  409. X}
  410. X
  411. X/* escape - interpret backslash sequences (this function is too big) */
  412. X
  413. Xhidden char *escape(s)
  414. Xregister char *s;
  415. X{
  416. X    static char buf[BUFSIZ];
  417. X    register char *cp = buf;
  418. X
  419. X    while (*s && cp < buf+BUFSIZ-1) {           /* don't overflow the buffer */
  420. X    register char ch;
  421. X    if (*s != '\\') {                       /* ordinary character */
  422. X        *cp++ = *s++;
  423. X    } else if (isdigit(*++s) && *s < '8') { /* \nnn octal code */
  424. X        int c, i;
  425. X        sscanf(s,"%3o",&c);
  426. X        *cp++ = c;
  427. X        i = 1;
  428. X            s++;
  429. X        while (i++ < 3 && isdigit(*s) && *s <'8')
  430. X        s++;
  431. X    } else if ((ch = *s++) == 0) {          /* at string terminator */
  432. X        break;
  433. X    } else if (ch == 'b') {                 /* \b becomes backspace */
  434. X        *cp++ = '\b';
  435. X    } else if (ch == 'f') {                 /* \f becomes formfeed */
  436. X        *cp++ = '\f';
  437. X    } else if (ch == 'n') {                 /* \n becomes newline */
  438. X        *cp++ = '\n';
  439. X    } else if (ch == 'r') {                 /* \r becomes carriage ret */
  440. X        *cp++ = '\r';
  441. X    } else if (ch == 's') {                 /* \s becomes blank */
  442. X        *cp++ = ' ';
  443. X    } else if (ch == 't') {                 /* \t becomes tab */
  444. X        *cp++ = '\t';
  445. X    } else {                                /* \any becomes any */
  446. X        *cp++ = ch;
  447. X    }
  448. X    }
  449. X    *cp = '\0';                                 /* terminate the result */
  450. X    return(buf);
  451. X}
  452. END_OF_connect.c
  453. if test 5702 -ne `wc -c <connect.c`; then
  454.     echo shar: \"connect.c\" unpacked with wrong size!
  455. fi
  456. # end of overwriting check
  457. fi
  458. if test -f email.c -a "${1}" != "-c" ; then 
  459.   echo shar: Will not over-write existing file \"email.c\"
  460. else
  461. echo shar: Extracting \"email.c\" \(5428 characters\)
  462. sed "s/^X//" >email.c <<'END_OF_email.c'
  463. X/*++
  464. X/* NAME
  465. X/*    email
  466. X/* SUMMARY
  467. X/*    manipulate work files (mail in preparation)
  468. X/* PROJECT
  469. X/*    pc-mail
  470. X/* PACKAGE
  471. X/*    mailsh
  472. X/* SYNOPSIS
  473. X/*    #include "email.h"
  474. X/*
  475. X/*    int mail()
  476. X/* DESCRIPTION
  477. X/*      The functions in this module are responsible for manipulations 
  478. X/*    on work files and other mail messages in preparation.
  479. X/*
  480. X/*      mail() can be called either when the user has selected a work file in
  481. X/*    the mail box display or when the user wants to create a new letter.
  482. X/*
  483. X/*    The message file is displayed on the screen and the can choose
  484. X/*    to print, mail, edit or delete etc. the message.
  485. X/*
  486. X/*    The code in this module is a little tricky, to avoid that a work
  487. X/*    file exists without a metafile (for the mail box display). 
  488. X/* COMMANDS
  489. X/*    the program specified in the EDITOR environment variable,
  490. X/*    or a system-dependent default.
  491. X/* FILES
  492. X/*      temporary edit file in current directory
  493. X/*    work file and meta file in spool directory
  494. X/* SEE ALSO
  495. X/*      pager(3), pager(5), kbdinp(3), edit(3)
  496. X/* AUTHOR(S)
  497. X/*      W.Z. Venema
  498. X/*      Eindhoven University of Technology
  499. X/*      Department of Mathematics and Computer Science
  500. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  501. X/* CREATION DATE
  502. X/*    Tue May 12 15:35:20 GMT+1:00 1987
  503. X/* LAST MODIFICATION
  504. X/*    Mon Apr  4 23:39:13 MET 1988
  505. X/* VERSION/RELEASE
  506. X/*    1.3
  507. X/*--*/
  508. X
  509. X#include <sys/types.h>
  510. X#include <sys/stat.h>
  511. X#include <errno.h>
  512. X#include "defs.h"
  513. X#include "path.h"
  514. X#include "dir.h"
  515. X#include "pager.h"
  516. X#include "screen.h"
  517. X#include "mailsh.h"
  518. X#include "status.h"
  519. X
  520. X/* forward declarations */
  521. X
  522. Xhidden void junk_work();
  523. Xhidden int queue_work();
  524. Xhidden int edit_work();
  525. Xhidden int show_work();
  526. Xhidden int send_work();
  527. Xhidden int hold_work();
  528. Xhidden int label_work();
  529. X
  530. Xhidden File *workfile = 0;            /* pager file */
  531. X
  532. X/* mail - user has made a choice. show message at cursor */
  533. X
  534. Xpublic int mail()
  535. X{
  536. X    static Screen screen[] = {
  537. X    'C',    "Close",    hold_work,"Send message later, return to main menu",
  538. X    'D',    "Delete",       delete,    delcurr,
  539. X    'E',    "Edit",        edit_work,"Edit this message",
  540. X    'M',    "Mail",        send_work,"Send this message to destination",
  541. X    'P',    "Print",    print,    printcurr,
  542. X    PGUP,    PgUp,        pu_pager,pageup,
  543. X    PGDN,    PgDn,        pd_pager,pagedn,
  544. X    UP,    "Up",           up_pager,csrup,
  545. X    DOWN,    "Down",         dn_pager,csrdn,
  546. X    0,    0,              show_work,
  547. X    "(Reading a message in preparation)",
  548. X    };
  549. X    struct stat s;
  550. X
  551. X    if (stat(message,&s) && errno == ENOENT)    /* if new message file */
  552. X    edit_work();                /* invoke editor first */
  553. X    kbdinp(screen);                /* ask disposition */
  554. X    junk_work();                /* destroy mail pager file */
  555. X    return(S_REDRAW);                /* say screen was changed */
  556. X}
  557. X
  558. X/* show_work - show work file or error message in middle window */
  559. X
  560. Xhidden int show_work()
  561. X{
  562. X    if (workfile) {                /* check pager file exists */
  563. X    set_pager(workfile);            /* select existent display */
  564. X    } else if (rd_pager(workfile = open_pager(),message)) {/* create display */
  565. X    mesg_pager(workfile,m_msgread);        /* cannot display message */
  566. X    }
  567. X    ds_pager();                    /* (re)draw display */
  568. X    return(0);                    /* screen is up-to-date */
  569. X}
  570. X
  571. X/* junk_work - destroy work file display */
  572. X
  573. Xhidden void junk_work()
  574. X{
  575. X    if (workfile) {                /* no-op if no display */
  576. X    close_pager(workfile);            /* release memory */
  577. X    workfile = 0;                /* say it is gone */
  578. X    }
  579. X}
  580. X
  581. X/* edit_work - edit or create a work file */
  582. X
  583. Xhidden int edit_work()
  584. X{
  585. X    register int stat;
  586. X
  587. X    if (stat = edit(message,MAILFILE)) 
  588. X    errdisp(stat);                /* edit() had a problem */
  589. X    junk_work();                /* force new message display */
  590. X    return(S_REDRAW);                /* say screen has changed */
  591. X}
  592. X
  593. X/* hold_work - stop editing but do not yet mail a work file */
  594. X
  595. Xhidden int hold_work()
  596. X{
  597. X    static Screen screen[] = {
  598. X    STRING,    0,              label_work,int_error,
  599. X    0,    0,              0,
  600. X    getsummary,
  601. X    };
  602. X    struct stat s;
  603. X
  604. X    /*
  605. X    * The user has terminated an editor session, but does not yet want
  606. X    * to send the message off. The purpose of the following code is to
  607. X    * ask for a one-line summary, but only if such a comment does not yet
  608. X    * exist. The summary is used to identify the work file in the main
  609. X    * mail box display.
  610. X    */
  611. X
  612. X    if (stat(message,&s) || !stat(comment,&s)) {/* no msg, or comment exists */
  613. X    return(S_BREAK);            /* we are done here */
  614. X    } else {
  615. X    return(kbdinp(screen)|S_REDRAW);    /* ask for a summary */
  616. X    }
  617. X}
  618. X
  619. X/* label_work - save summary line to meta file */
  620. X
  621. Xhidden label_work(string)
  622. Xchar *string;
  623. X{
  624. X    register int stat;
  625. X
  626. X    if (stat = metafile(string,comment)) {    /* try to create meta file */
  627. X    errdisp(stat);                /* oops, notify the user */
  628. X    return(S_REDRAW);            /* say screen has changed */
  629. X    } else {
  630. X    chmod(comment,0444);            /* make comments read-only */
  631. X    junk_desk();                /* say mail box has changed */
  632. X    return(S_BREAK);            /* say no more work */
  633. X    }
  634. X}
  635. X
  636. X/* send_work - user wants to send work file, ask for destination */
  637. X
  638. Xhidden int send_work()
  639. X{
  640. X    static Screen screen[] = {
  641. X    STRING,    0,              queue_work,int_error,
  642. X    0,    0,              when,
  643. X    "Press ESC to cancel. Send message to:",
  644. X    };
  645. X    return(kbdinp(screen)|S_REDRAW);
  646. X}
  647. X
  648. X/* queue_work - spool mail, delete work file and meta file */
  649. X
  650. Xhidden int queue_work(to)
  651. Xchar *to;
  652. X{
  653. X    register int stat;
  654. X
  655. X    if (stat = submit(message,to)) {
  656. X    errdisp(stat);                /* cannot queue message */
  657. X    return(S_REDRAW);            /* say screen has changed */
  658. X    } else {
  659. X    return(unspool()|S_BREAK);        /* remove work and meta file */
  660. X    }
  661. X}
  662. END_OF_email.c
  663. if test 5428 -ne `wc -c <email.c`; then
  664.     echo shar: \"email.c\" unpacked with wrong size!
  665. fi
  666. # end of overwriting check
  667. fi
  668. if test -f gp.h -a "${1}" != "-c" ; then 
  669.   echo shar: Will not over-write existing file \"gp.h\"
  670. else
  671. echo shar: Extracting \"gp.h\" \(5523 characters\)
  672. sed "s/^X//" >gp.h <<'END_OF_gp.h'
  673. X/*++
  674. X/* NAME
  675. X/*    gp 5
  676. X/* SUMMARY
  677. X/*    g-protocol internal definitions
  678. X/* PROJECT
  679. X/*    pc-mail
  680. X/* PACKAGE
  681. X/*    cico
  682. X/* SYNOPSIS
  683. X/*    #include "gp.h"
  684. X/* DESCRIPTION
  685. X/* .nf
  686. X
  687. X/* /* include-once file */
  688. X
  689. X#ifndef    GP
  690. X#define    GP
  691. X
  692. X#include <stdio.h>            /* needed for stderr */
  693. X
  694. X#define    MAXTRY        10        /* max nr of retries */
  695. X#define    CTRL(x)        ((x)^0100)    /* for ascii control characters */
  696. X#define    MIN(x,y)    ((x) < (y) ? (x) : (y))
  697. X#define    MAX(x,y)    ((x) > (y) ? (x) : (y))
  698. X
  699. X#define    ALARM        10        /* time-out interval */
  700. X#define    MAGIC        0xAAAA        /* checksum magic number */
  701. X#define    KCTRL        9        /* control packet */
  702. X
  703. X#define    FAIL        (-1)        /* corrupted packet */
  704. X#define    TIME        (-2)        /* timed out */
  705. X
  706. X/* 
  707. X* The protocol is defined in terms of message transmissions of 8-bit
  708. X* bytes. Each message includes one control byte plus a data segment
  709. X* of zero or more information bytes. (...)
  710. X* The control byte is partitioned into three fields as depicted below.
  711. X*    bit    7    6    5    4    3    2    1    0
  712. X*        t    t    x    x    x    y    y    y
  713. X* The t bits indicate a packet type and determine the interpretation
  714. X* to be placed on the xxx and yyy the fields. The various interpretations
  715. X* are as follows:
  716. X*    tt    interpretation
  717. X*    00    control packet
  718. X*    10    data packet
  719. X*    11    short data packet
  720. X*    01    alternate channel
  721. X* A data segment accompanies all non-control packets. (...) Type 01 packets
  722. X* are never used by UUCP (...)
  723. X*/
  724. X
  725. X#define    TYPE(x)        ((x)&0300)    /* extract message field */
  726. X
  727. X#define    CONTROL        0000        /* control message */
  728. X#define    DATA        0200        /* data, fixed size */
  729. X#define    SHORT        0300        /* short (variable) length data */
  730. X#define    ALTCH        0100        /* alternate channel (unused) */
  731. X
  732. X/*
  733. X* The sequence number of a non-control packet is given by the xxx field.
  734. X* Control packets are not sequenced. The newest sequence number,
  735. X* excluding duplicate transmissions, accepted by a receiver is placed in 
  736. X* the yyy field of non-control packets sent to the `other' receiver.
  737. X*/
  738. X
  739. X#define    TVAL(x)        (((x)&0377)>>6)    /* extract message type */
  740. X#define    MVAL(x)        (((x)&070)>>3)    /* extract control message */
  741. X#define    SVAL(x)        (((x)&070)>>3)    /* extract S(equence) value */
  742. X#define    RVAL(x)        ((x)&07)    /* extract R(received) value */
  743. X#define    IVAL(x)        ((x)&07)    /* extract init value */
  744. X#define    SFLD(x)        (((x)&07)<<3)    /* create S(equence) field */
  745. X#define    RFLD(x)        ((x)&07)    /* create R(received) field */
  746. X#define    IFLD(x)        ((x)&07)    /* create init field */
  747. X
  748. X/*
  749. X* There are no data bytes associated with a control packet, the xxx field
  750. X* is interpreted as a control message, and the yyy field is a value 
  751. X* accompanying the control message. The control messages are listed
  752. X* below in decreasing priority. That is, if several control messags
  753. X* are to be sent, the lower-numbered ones are sent first.
  754. X*    xxx    name    yyy
  755. X*    1    CLOSE    n/a
  756. X*    2    RJ    last correctly received sequence number
  757. X*    3    SRJ    sequence number to retransmit
  758. X*    4    RR    last correctly received sequence number
  759. X*    5    INITC    window size
  760. X*    6    INITB    data segment size
  761. X*    7    INITA    window size
  762. X*/
  763. X
  764. X#define    MESG(x)        ((x)&070)    /* extract control message field */
  765. X
  766. X#define    CLOSE        0010        /* close message */
  767. X#define    RJ        0020        /* reject message */
  768. X#define    SRJ        0030        /* selective-reject message (unused) */
  769. X#define    RR        0040        /* received ok message */
  770. X#define    INITC        0050        /* initialization message */
  771. X#define    INITB        0060        /* initialization message */
  772. X#define    INITA        0070        /* initialization message */
  773. X
  774. X/* declarations for tiny systems without tty driver, timer support etc. */
  775. X
  776. X#ifndef    unix
  777. X
  778. X#define    read        xread
  779. X#define    write        xwrite
  780. X#define    alarm(x)    /* nothing */
  781. X#define    signal(x,y)    /* nothing */
  782. X#define    DEBUG(x,y,z)    if (dflag >= x) printf(y,z)
  783. X
  784. Xextern int dflag;
  785. X
  786. X#else
  787. X
  788. X#define    DEBUG(l,f,s)    if (Debug >= l) fprintf(stderr,f,s)
  789. X
  790. Xextern int Debug;
  791. X
  792. X#endif
  793. X
  794. X/* 
  795. X* We use one data structre for communication between various levels
  796. X* of the g-protocol implementation. Fields in parentheses are relevant
  797. X* only when a packet holds data.
  798. X*    field    meaning                set by
  799. X*    c    message type            gwrite(), grpack()
  800. X*    (k    data segment length        galloc(), grpack())
  801. X*    (chk    16-bit checksum            packet i/o functions)
  802. X*    (len    max. data segment length    galloc(), gwrite(), grpack())
  803. X*    (data    start of "len" bytes        this field is fixed)
  804. X*    (segl    nbr of data bytes left        gread())
  805. X*    (segp    start of "segl" bytes        gread())
  806. X*/
  807. X
  808. X/* structure for communication between various program layers */
  809. X
  810. Xtypedef struct {
  811. X    char k;                /* message segment size */
  812. X    char c;                /* message type */
  813. X    int chk;                /* data checksum */
  814. X    short segl;                /* nr of data bytes left */
  815. X    char *segp;                /* start of the "segl" bytes */
  816. X    short len;                /* maximum data segment size */
  817. X    char data[1];            /* actually a lot of characters */
  818. X} Packet;
  819. X
  820. X/* functions that manipulate packets */
  821. X
  822. Xextern Packet *grproto();        /* take packet from input queue */
  823. Xextern void gfree();            /* release input packet */
  824. Xextern Packet *galloc();        /* allocate output packet */
  825. Xextern void gwproto();            /* place packet in output queue */
  826. Xextern void gfail();            /* panic button */
  827. Xextern void gsctrl();            /* send one control packet */
  828. Xextern void gsdata();            /* send one data packet */
  829. Xextern int grpack();            /* receive one packet */
  830. X
  831. Xextern int seglen[];            /* data segment size table */
  832. X
  833. X/* standard unix library */
  834. X
  835. Xextern char *malloc();
  836. X
  837. X#endif    /* GP */
  838. X/* AUTHOR(S)
  839. X/*    W.Z. Venema
  840. X/*    Eindhoven University of Technology
  841. X/*    Department of Mathematics and Computer Science
  842. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  843. X/* CREATION DATE
  844. X/*    Sun Apr 19 12:41:37 GMT+1:00 1987
  845. X/* LAST MODIFICATION
  846. X/*    Mon Apr  4 23:40:57 MET 1988
  847. X/* VERSION/RELEASE
  848. X/*    1.3
  849. X/*--*/
  850. END_OF_gp.h
  851. if test 5523 -ne `wc -c <gp.h`; then
  852.     echo shar: \"gp.h\" unpacked with wrong size!
  853. fi
  854. # end of overwriting check
  855. fi
  856. if test -f gpres.c -a "${1}" != "-c" ; then 
  857.   echo shar: Will not over-write existing file \"gpres.c\"
  858. else
  859. echo shar: Extracting \"gpres.c\" \(6391 characters\)
  860. sed "s/^X//" >gpres.c <<'END_OF_gpres.c'
  861. X/*++
  862. X/* NAME
  863. X/*    gpres.c 3
  864. X/* SUMMARY
  865. X/*    g-protocol general interface
  866. X/* PROJECT
  867. X/*    pc-mail
  868. X/* PACKAGE
  869. X/*    cico
  870. X/* SYNOPSIS
  871. X/*    int gopen(fd);
  872. X/*    int fd;
  873. X/*
  874. X/*    int gwrite(fd,buf,len)
  875. X/*    int fd,len;
  876. X/*    char *buf;
  877. X/*
  878. X/*    int gread(fd,buf,len)
  879. X/*    int fd,len;
  880. X/*    char *buf;
  881. X/*
  882. X/*    int gclose(fd)
  883. X/*    int fd;
  884. X/* DESCRIPTION
  885. X/*    The functions in this module present an interface that closely
  886. X/*    resembles the unix kernel i/o interface.
  887. X/*
  888. X/*    gopen() handles the initial message exchange. fd should be
  889. X/*    connected to a tty line. gopen() normally returns a zero value.
  890. X/*
  891. X/*    gwrite() returns the number of bytes `written' to the remote system.
  892. X/*    It should be considered an error if this is not equal to the number
  893. X/*    of bytes requested.
  894. X/*    A zero-length write should be used to indicate EOF during file transfer.
  895. X/*
  896. X/*    gread() returns the requested number of bytes or the number of
  897. X/*    bytes sent by the remote system, whichever is smaller.
  898. X/*    A zero-length read indicates EOF during file transfer.
  899. X/*
  900. X/*    gclose() shuts the protocol down, but does not otherwise change
  901. X/*    communications line parameters. It normally returns a zero value.
  902. X/* FUNCTIONS AND MACROS
  903. X/*    galloc(), gfree(), gsproto(), grproto()
  904. X/* DIAGNOSTICS
  905. X/*    All functions return -1 in case of unrecoverable problems.
  906. X/* BUGS
  907. X/*    All g protocol routines assume that the XON/XOFF flow control
  908. X/*    has been turned off.
  909. X/*    Some parts of the code rely on 8-bit bytes, 16-bit short integers.
  910. X/* AUTHOR(S)
  911. X/*    W.Z. Venema
  912. X/*    Eindhoven University of Technology
  913. X/*    Department of Mathematics and Computer Science
  914. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  915. X/* CREATION DATE
  916. X/*    Sun Apr 19 12:41:37 GMT+1:00 1987
  917. X/* LAST MODIFICATION
  918. X/*    Mon Apr  4 23:41:36 MET 1988
  919. X/* VERSION/RELEASE
  920. X/*    1.3
  921. X/*--*/
  922. X
  923. X#include <setjmp.h>
  924. X#include "gp.h"
  925. X
  926. X/* local and forward declarations */
  927. X
  928. Xstatic jmp_buf failbuf;
  929. Xstatic void gpeek(),gpoke(),memcpy();
  930. X
  931. X/* gfail - exception handling */
  932. X
  933. Xvoid gfail()
  934. X{
  935. X    longjmp(failbuf,1);
  936. X}
  937. X
  938. X/* gopen - not quite an analogon of unix open(2) */
  939. X
  940. Xint gopen(fd)
  941. Xint fd;
  942. X{
  943. X    return(ginit(fd));        /* do packet stuff elsewhere */
  944. X}
  945. X
  946. X/* gwrite - g-protocol analogon of unix write(2) */
  947. X
  948. Xgwrite(fd,data,len)
  949. Xint fd,len;
  950. Xchar *data;
  951. X{
  952. X    /* set up exception handling */
  953. X
  954. X    if (setjmp(failbuf))            /* in case gsproto fails */
  955. X    return(FAIL);                /* it just did */
  956. X
  957. X    /* handle special case of zero-length writes separately */
  958. X
  959. X    if (len <= 0) {                /* end-of-file message */
  960. X    register Packet *pk = galloc();        /* allocate output packet */
  961. X    gpoke(pk,data,len);            /* make null-data packet */
  962. X    gsproto(fd,pk);                /* send to other side */
  963. X    } else {                    /* true data message */
  964. X    register int shot;            /* quantum size */
  965. X    register int rest;            /* amount left to do */
  966. X    for (rest = len; rest > 0; rest -= shot,data += shot) {
  967. X        register Packet *pk = galloc();    /* allocate output packet */
  968. X        gpoke(pk,data,shot = MIN(pk->len,rest));/* fill the packet */
  969. X        gsproto(fd,pk);
  970. X    }
  971. X    }
  972. X    return(len);                /* no problems detected */
  973. X}
  974. X
  975. X/* gread - g-protocol analogon of unix read(2) */
  976. X
  977. Xgread(fd,data,len)
  978. Xint fd,len;
  979. Xchar *data;
  980. X{
  981. X    static Packet *pk;                /* our byte stock */
  982. X    register int igot;                /* our return value */
  983. X
  984. X    /* set up exception handling */
  985. X
  986. X    if (setjmp(failbuf))            /* in case grproto fails */
  987. X    return(FAIL);                /* it just did */
  988. X
  989. X    /* if no bytes in stock, get some fresh ones and see how much we got */
  990. X
  991. X    if (pk == 0 || pk->segl <= 0)        /* we are out of data */
  992. X    gpeek(pk = grproto(fd));        /* get fresh packet */
  993. X
  994. X    /* return as many bytes as asked, or as in stock, whichever is less */
  995. X
  996. X    if ((igot = MIN(len,pk->segl)) > 0) {
  997. X    memcpy(data,pk->segp,igot);        /* copy to caller's buffer */
  998. X    pk->segp += igot;            /* update stock pointer */
  999. X    pk->segl -= igot;            /* update stock count */
  1000. X    }
  1001. X    if (pk->segl <= 0)                /* if we exhausted the stock */
  1002. X    gfree(pk);                /* release packet */
  1003. X    return(igot);                /* no problems detected */
  1004. X}
  1005. X
  1006. X/* gclose - turn g protocol off */
  1007. X
  1008. Xgclose(fd)
  1009. Xint fd;
  1010. X{
  1011. X    return(gfinit(fd));                /* not here! */
  1012. X}
  1013. X
  1014. X/* 
  1015. X* "Each transmitter is constrained to observe the maximum data segment"
  1016. X* "size established during initial synchronization by the receiver that"
  1017. X* "it sends to. (...) `short' packets have zero or more data bytes but less"
  1018. X* "than the maximum. The first one or two bytes of the data segment of"
  1019. X* "a short packet are `count' bytes that indicate the difference between"
  1020. X* "the maximum size and the number of bytes in the short segment. If the"
  1021. X* "difference is less than 127, one count byte is used. If the difference"
  1022. X* "exceeds 127, then the low-order seven bits of the difference are put"
  1023. X* "in the first data byte and the remaining high-order bit is set as an"
  1024. X* "indication that the remaining bits of the difference are in the second"
  1025. X* "byte.
  1026. X*/
  1027. X
  1028. X/* gpoke - prepare packet for transmission */
  1029. X
  1030. Xstatic void gpoke(pk,data,len)
  1031. Xregister Packet *pk;
  1032. Xint len;
  1033. Xchar *data;
  1034. X{
  1035. X    register int diff = pk->len-len;        /* packet/data size mismatch */
  1036. X
  1037. X    pk->segp = pk->data;            /* set up write pointer */
  1038. X    pk->segl = len;                /* actual segment length */
  1039. X    if (diff < 0 || len < 0) {
  1040. X    DEBUG(7,"gpoke: trouble\n","");        /* something very wrong */
  1041. X    gfail();
  1042. X    /* NOTREACHED */
  1043. X    } else if (diff == 0) {
  1044. X    pk->c = DATA;                /* long data segment */
  1045. X    } else if (diff <= 127) {
  1046. X    pk->c = SHORT;                /* short data segment */
  1047. X    *pk->segp++ = diff;            /* one difference byte */
  1048. X    } else if (diff > 127) {
  1049. X    pk->c = SHORT;                /* tiny data segment */
  1050. X    *pk->segp++ = diff|0200;        /* two difference bytes */
  1051. X    *pk->segp++ = diff>>7;
  1052. X    }
  1053. X    memcpy(pk->segp,data,pk->segl);        /* copy data into packet */
  1054. X}
  1055. X
  1056. X/* gpeek - prepare newly packet for reading */
  1057. X
  1058. Xstatic void gpeek(pk)
  1059. Xregister Packet *pk;
  1060. X{
  1061. X    register int diff;
  1062. X
  1063. X    pk->segp = pk->data;            /* set up read pointer */
  1064. X    if (TYPE(pk->c) == DATA) {
  1065. X    diff = 0;                /* long data segment */
  1066. X    } else if (TYPE(pk->c) != SHORT) {
  1067. X    DEBUG(7,"gread: trouble\n","");        /* something funny */
  1068. X    gfail();
  1069. X    /* NOTREACHED */
  1070. X    } else if ((diff = *pk->segp++&0377)&0200) {/* short data segment */
  1071. X    diff = (diff&0177)|((*pk->segp++&0377)<<7);
  1072. X    }
  1073. X    pk->segl = pk->len-diff;            /* actual segment size */
  1074. X    DEBUG(9,"rcv: data %d bytes\n",pk->segl);
  1075. X}
  1076. X
  1077. X/* memcpy - not-so-efficient implementation */
  1078. X
  1079. Xstatic void memcpy(dst,src,len)
  1080. Xregister char *dst,*src;
  1081. Xregister int len;
  1082. X{
  1083. X    while (len-- > 0)
  1084. X    *dst++ = *src++;
  1085. X}
  1086. END_OF_gpres.c
  1087. if test 6391 -ne `wc -c <gpres.c`; then
  1088.     echo shar: \"gpres.c\" unpacked with wrong size!
  1089. fi
  1090. # end of overwriting check
  1091. fi
  1092. if test -f ktrans.c -a "${1}" != "-c" ; then 
  1093.   echo shar: Will not over-write existing file \"ktrans.c\"
  1094. else
  1095. echo shar: Extracting \"ktrans.c\" \(4983 characters\)
  1096. sed "s/^X//" >ktrans.c <<'END_OF_ktrans.c'
  1097. X/*++
  1098. X/* NAME
  1099. X/*    ktrans 3
  1100. X/* SUMMARY
  1101. X/*    k-protocol strategy routines
  1102. X/* PACKAGE
  1103. X/*    uucp across the TUEnet
  1104. X/* SYNOPSIS
  1105. X/*    #include "kp.h"
  1106. X/*
  1107. X/*    krproto(fd,data,size) 
  1108. X/*    int fd, *size;
  1109. X/*    char data[MAXPACKSIZ];
  1110. X/*
  1111. X/*    kwproto(fd,data,size) 
  1112. X/*    int fd, size;
  1113. X/*    char data[MAXPACKSIZ];
  1114. X/*
  1115. X/*    kclsproto(fd)
  1116. X/*    int fd;
  1117. X/* DESCRIPTION
  1118. X/*    The functions in this file take care of handshake and error
  1119. X/*    detection/recovery. The read/write functions return through an
  1120. X/*    external function kfail() in case of fatal errors, or protocol 
  1121. X/*    termination by the network partner.
  1122. X/*
  1123. X/*    The following packet types are used:
  1124. X/*
  1125. X/* .nf
  1126. X/* .in +5
  1127. X/*    D packets contain data.
  1128. X/*    Y packets are sent when a correct data packet was received.
  1129. X/*    N packets are sent when incorrect data was received.
  1130. X/*    A packets are sent to shut down the k protocol.
  1131. X/* .fi
  1132. X/*
  1133. X/*    Krproto() sends the data and either returns normally, or through 
  1134. X/*    kfail().
  1135. X/*
  1136. X/*    Kwproto() returns the received data or returns through kfail().
  1137. X/*
  1138. X/*    Kclsproto() sends the protocol termination sequence to the other 
  1139. X/*    side, either to signal the end of transfers, or to confirm
  1140. X/*    reception of an end-of-protocol sequence.
  1141. X/*
  1142. X/*    The strategy for sending data is as follows:
  1143. X/*
  1144. X/*    Send packet.
  1145. X/*    If (ACK for last packet) or (NAK for next packet) received, terminate.
  1146. X/*    If (NAK for last packet) or no response received, retransmit.
  1147. X/*    If data received with previous packet nr, ignore and wait for NAK.
  1148. X/*    If data received with next packet nr, NAK that data and terminate.
  1149. X/*    Otherwise (bad packet number, unexpected packet type) abort.
  1150. X/*
  1151. X/*    The strategy for receiving data is complementary:
  1152. X/*
  1153. X/*    Wait for packet
  1154. X/*    If expected packet received, ACK it and terminate.
  1155. X/*    If previous data packet received, ACK it and wait for next packet.
  1156. X/*    If bad packet received, send NAK for expected packet.
  1157. X/*    If nothing received, wait for another packet.
  1158. X/*    Otherwise (bad packet number, unexpected packet type) abort.
  1159. X/* FUNCTIONS AND MACROS
  1160. X/*    kspack, krpack, kfail
  1161. X/* AUTHOR(S)
  1162. X/*    Wietse Venema
  1163. X/*    Eindhoven University of Technology
  1164. X/*    Department of Mathematics and Computer Science
  1165. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1166. X/* CREATION DATE
  1167. X/*    Mon Feb  3 13:12:08 MET 1986
  1168. X/* LAST MODIFICATION
  1169. X/*    Mon Apr  4 23:43:42 MET 1988
  1170. X/* VERSION/RELEASE
  1171. X/*    1.4
  1172. X/*--*/
  1173. X
  1174. X#include "kp.h"
  1175. X
  1176. Xstatic char recpkt[MAXPACKSIZ];            /* receive packet buffer */
  1177. Xstatic int  n = 0;                /* packet number */
  1178. X
  1179. Xkwproto( fd, packet, size)
  1180. Xint fd;
  1181. Xchar *packet;
  1182. Xint size;
  1183. X{
  1184. X    int num, numtry;                            /* Packet number, tries */
  1185. X    int len;
  1186. X
  1187. X    kspack(fd, 'D',n,size,packet);          /* Send a D packet */
  1188. X
  1189. X    for (numtry = 0; numtry < MAXTRY; numtry++) {
  1190. X    switch(krpack(fd,&num,&len,recpkt))     /* What was the reply? */
  1191. X    {
  1192. X    case 'D':                    /* DATA */
  1193. X        if ((num+1)%64 == n) {        /* Previous packet ? */
  1194. X        numtry = 0;            /* Reset counter */
  1195. X        break;                /* Don't ack it; read again */
  1196. X        } else if (num != (n+1)%64)        /* Fatal error, unless it */
  1197. X        kfail();                /* carries next packet number */
  1198. X        kspack(fd,'N',num,0,NULLP);       /* Can't use data now */
  1199. X
  1200. X    case 'N':                           /* NAK */
  1201. X        if (n == num) {            /* Send another one, */
  1202. X        kspack(fd, 'D',n,size,packet);
  1203. X        break;
  1204. X        }
  1205. X        num = (--num<0 ? 63:num);     /* unless NAK for next packet */
  1206. X
  1207. X    case 'Y':                           /* ACK */
  1208. X        if (n != num) kfail();          /* If wrong ACK, fail */
  1209. X        n = (n+1)%64;                   /* Bump packet count */
  1210. X        return;
  1211. X
  1212. X    case TIME:                /* No response */
  1213. X    case FAIL:                /* Bad packet */
  1214. X        kspack(fd, 'D',n,size,packet);
  1215. X        break;                  /* Send data packet again */
  1216. X
  1217. X    default: 
  1218. X        kfail();                           /* Something else, abort */
  1219. X    }
  1220. X    }
  1221. X    kfail();                        /* Too may retries, abort */
  1222. X}
  1223. X
  1224. Xkrproto( fd, packet, size)
  1225. Xint fd;
  1226. Xchar *packet;
  1227. Xint *size;
  1228. X{
  1229. X    int num, numtry;                            /* Packet number, tries */
  1230. X
  1231. X    for (numtry = 0; numtry < MAXTRY; numtry++) 
  1232. X    {
  1233. X    switch (krpack(fd,&num,size,packet))    /* Get packet */
  1234. X    {
  1235. X    case 'D':
  1236. X        if (num == n) {            /* Right packet? */
  1237. X        kspack(fd,'Y',n,0,NULLP);    /* Acknowledge the packet */
  1238. X        n = (n+1)%64;            /* Bump packet number, mod 64 */
  1239. X        return;
  1240. X        } else if (num == ((n==0) ? 63:n-1)) { /* Previous packet? */
  1241. X        kspack(fd,'Y',num,0,NULLP);    /* Re-ack previous packet */
  1242. X        numtry = 0;                    /* Reset counter */
  1243. X        break;                /* Read another packet */
  1244. X        } else
  1245. X        kfail();            /* Sorry, wrong number */
  1246. X
  1247. X    case TIME:                /* No packet */
  1248. X        break;                /* Don't NAK */
  1249. X
  1250. X    case FAIL:                /* Bad packet */
  1251. X        kspack(fd,'N',n,0,NULLP);        /* Return a NAK */
  1252. X        break;                /* Read another packet */
  1253. X
  1254. X    default:
  1255. X        kfail();                /* Something else, abort */
  1256. X    }
  1257. X    }
  1258. X    kfail();                        /* Too may retries, abort */
  1259. X}
  1260. X
  1261. Xkclsproto( fd)
  1262. Xint fd;
  1263. X{
  1264. X    kspack( fd, 'A', 0, 0, NULLP);        /* Send an 'A' packet */
  1265. X    kspack( fd, 'A', 0, 0, NULLP);        /* and another two since */
  1266. X    kspack( fd, 'A', 0, 0, NULLP);        /* we won't get ACKs */
  1267. X    return 0;
  1268. X}
  1269. END_OF_ktrans.c
  1270. if test 4983 -ne `wc -c <ktrans.c`; then
  1271.     echo shar: \"ktrans.c\" unpacked with wrong size!
  1272. fi
  1273. # end of overwriting check
  1274. fi
  1275. if test -f makefile.msc -a "${1}" != "-c" ; then 
  1276.   echo shar: Will not over-write existing file \"makefile.msc\"
  1277. else
  1278. echo shar: Extracting \"makefile.msc\" \(5643 characters\)
  1279. sed "s/^X//" >makefile.msc <<'END_OF_makefile.msc'
  1280. XRM    = rm -f
  1281. XMV    = mv
  1282. XCC    = cl
  1283. XAS    = masm
  1284. X
  1285. XSHOBJ1    = call.o email.o file.o screen.o mbox.o desk.o
  1286. XSHOBJ2    = kbdinp.o pager.o window.o setup.o errdisp.o invoke.o
  1287. XSHOBJ3    = makework.o mailfile.o deskutil.o submit.o edit.o alias.o
  1288. XSHLIBS    = shlib1.lib shlib2.lib shlib3.lib
  1289. X
  1290. XSMOBJ    = smail.o unalias.o hsearch.o
  1291. X
  1292. XRMOBJ    = rmail.o
  1293. X
  1294. XCMOBJ    = cmail.o invoke.o
  1295. X
  1296. XCIOBJ1    = comm.o connect.o getwork.o kphys.o kpres.o ktrans.o logs.o
  1297. XCIOBJ2    = newseqno.o protomsg.o rmtname.o scanwork.o sendwork.o startup.o
  1298. XCIOBJ3    = switcher.o xpres.o gpres.o gtrans.o gphys.o
  1299. XCILIBS    = cilib1.lib cilib2.lib cilib3.lib
  1300. X
  1301. XGENSRC    = dir.c myalloc.c params.c path.c newseqno.c ascf.c spoolfil.c \
  1302. X    str.c
  1303. XGENOBJ    = dir.o myalloc.o params.o path.o newseqno.o ascf.o spoolfil.o \
  1304. X    str.o
  1305. X
  1306. XCFLAGS    = -Gs
  1307. XLDFLAGS    = -F 2000
  1308. X
  1309. X.s.o:
  1310. X    $(AS) $*.s ;
  1311. X    $(MV) $*.obj $*.o
  1312. X
  1313. X.c.o:
  1314. X    $(CC) $(CFLAGS) -c $*.c
  1315. X    $(MV) $*.obj $*.o
  1316. X
  1317. Xall:    mail.exe smail.exe rmail.exe cico.exe cmail.exe
  1318. X
  1319. Xmail.exe: mailsh.o $(SHLIBS) libgen.lib
  1320. X    $(CC) $(LDFLAGS) -o mail mailsh.o -link $(SHLIBS) libgen.lib \lib\termcap
  1321. X    -exepack mail.exe junk
  1322. X    $(MV) junk mail.exe
  1323. X
  1324. Xsmail.exe: $(SMOBJ) libgen.lib
  1325. X    $(CC) $(LDFLAGS) -o smail $(SMOBJ) -link libgen.lib
  1326. X    -exepack smail.exe junk
  1327. X    $(MV) junk smail.exe
  1328. X
  1329. Xcmail.exe: cmail.o libgen.lib
  1330. X    $(CC) $(LDFLAGS) -o cmail cmail.o invoke.o -link libgen.lib
  1331. X    -exepack cmail.exe junk
  1332. X    $(MV) junk cmail.exe
  1333. X
  1334. Xrmail.exe: rmail.o libgen.lib
  1335. X    $(CC) $(LDFLAGS) -o rmail rmail.o -link libgen.lib
  1336. X    -exepack rmail.exe junk
  1337. X    $(MV) junk rmail.exe
  1338. X
  1339. Xcico.exe: cico.o comport.o $(CILIBS)
  1340. X    $(CC) $(LDFLAGS) -o junk cico.o comport.o -link $(CILIBS) libgen
  1341. X    -exepack junk.exe cico.exe 
  1342. X    $(RM) junk.exe
  1343. X
  1344. Xshlib1.lib: $(SHOBJ1)
  1345. X    $(RM) shlib1.lib
  1346. X    lib shlib1.lib $(SHOBJ1) ;
  1347. X
  1348. Xshlib2.lib: $(SHOBJ2)
  1349. X    $(RM) shlib2.lib
  1350. X    lib shlib2.lib $(SHOBJ2) ;
  1351. X
  1352. Xshlib3.lib: $(SHOBJ3)
  1353. X    $(RM) shlib3.lib
  1354. X    lib shlib3.lib $(SHOBJ3) ;
  1355. X
  1356. Xlibgen.lib: $(GENOBJ)
  1357. X    $(RM) $@
  1358. X    lib libgen $(GENOBJ) ;
  1359. X
  1360. Xcilib1.lib: $(CIOBJ1)
  1361. X    $(RM) $@
  1362. X    lib cilib1 $(CIOBJ1) ;
  1363. X
  1364. Xcilib2.lib: $(CIOBJ2)
  1365. X    $(RM) $@
  1366. X    lib cilib2 $(CIOBJ2) ;
  1367. X
  1368. Xcilib3.lib: $(CIOBJ3)
  1369. X    $(RM) $@
  1370. X    lib cilib3 $(CIOBJ3) ;
  1371. X
  1372. Xdepend:
  1373. X    @grep '^# *include *"' *.c|sed 's/c:# *include *"\([^"]*\)".*/o:    \1/g'
  1374. X
  1375. Xalias.o:    defs.h
  1376. Xalias.o:    path.h
  1377. Xalias.o:    pager.h
  1378. Xalias.o:    mailsh.h
  1379. Xalias.o:    screen.h
  1380. Xalias.o:    status.h
  1381. Xascf.o:    defs.h
  1382. Xascf.o:    ascf.h
  1383. Xcall.o:    defs.h
  1384. Xcall.o:    path.h
  1385. Xcall.o:    screen.h
  1386. Xcall.o:    pager.h
  1387. Xcall.o:    mailsh.h
  1388. Xcico.o:    defs.h
  1389. Xcico.o:    logs.h
  1390. Xcico.o:    params.h
  1391. Xcico.o:    comm.h
  1392. Xcico.o:    status.h
  1393. Xcico.o:    path.h
  1394. Xcmail.o:    defs.h
  1395. Xcmail.o:    dir.h
  1396. Xcmail.o:    path.h
  1397. Xcmail.o:    status.h
  1398. Xcomm.o:    defs.h
  1399. Xcomm.o:    params.h
  1400. Xcomm.o:    comm.h
  1401. Xconnect.o:    defs.h
  1402. Xconnect.o:    params.h
  1403. Xconnect.o:    status.h
  1404. Xconnect.o:    comm.h
  1405. Xconnect.o:    logs.h
  1406. Xconnect.o:    sysdep.h
  1407. Xdesk.o:    defs.h
  1408. Xdesk.o:    mailsh.h
  1409. Xdesk.o:    path.h
  1410. Xdesk.o:    dir.h
  1411. Xdesk.o:    pager.h
  1412. Xdesk.o:    screen.h
  1413. Xdesk.o:    status.h
  1414. Xdesk.o:    window.h
  1415. Xdeskutil.o:    defs.h
  1416. Xdeskutil.o:    pager.h
  1417. Xdeskutil.o:    mailsh.h
  1418. Xdeskutil.o:    screen.h
  1419. Xdeskutil.o:    status.h
  1420. Xdir.o:    defs.h
  1421. Xdir.o:    dir.h
  1422. Xedit.o:    defs.h
  1423. Xedit.o:    path.h
  1424. Xedit.o:    mailsh.h
  1425. Xedit.o:    status.h
  1426. Xemail.o:    defs.h
  1427. Xemail.o:    path.h
  1428. Xemail.o:    dir.h
  1429. Xemail.o:    pager.h
  1430. Xemail.o:    screen.h
  1431. Xemail.o:    mailsh.h
  1432. Xemail.o:    status.h
  1433. Xerrdisp.o:    defs.h
  1434. Xerrdisp.o:    screen.h
  1435. Xerrdisp.o:    pager.h
  1436. Xerrdisp.o:    status.h
  1437. Xerrdisp.o:    window.h
  1438. Xfile.o:    defs.h
  1439. Xfile.o:    screen.h
  1440. Xfile.o:    pager.h
  1441. Xfile.o:    mailsh.h
  1442. Xfile.o:    dir.h
  1443. Xfile.o:    path.h
  1444. Xfile.o:    status.h
  1445. Xfile.o:    window.h
  1446. Xgetwork.o:    defs.h
  1447. Xgetwork.o:    logs.h
  1448. Xgetwork.o:    status.h
  1449. Xgetwork.o:    work.h
  1450. Xgetwork.o:    params.h
  1451. Xgetwork.o:    comm.h
  1452. Xgphys.o:    gp.h
  1453. Xgpres.o:    gp.h
  1454. Xgtrans.o:    gp.h
  1455. Xhsearch.o:    hsearch.h
  1456. Xinvoke.o:    defs.h
  1457. Xinvoke.o:    status.h
  1458. Xkbdinp.o:    defs.h
  1459. Xkbdinp.o:    mailsh.h
  1460. Xkbdinp.o:    screen.h
  1461. Xkbdinp.o:    window.h
  1462. Xkphys.o:    kp.h
  1463. Xkpres.o:    kp.h
  1464. Xktrans.o:    kp.h
  1465. Xlogs.o:    defs.h
  1466. Xlogs.o:    logs.h
  1467. Xlogs.o:    path.h
  1468. Xlogs.o:    status.h
  1469. Xmailfile.o:    defs.h
  1470. Xmailfile.o:    path.h
  1471. Xmailfile.o:    screen.h
  1472. Xmailfile.o:    mailsh.h
  1473. Xmailsh.o:    defs.h
  1474. Xmailsh.o:    path.h
  1475. Xmailsh.o:    status.h
  1476. Xmailsh.o:    mailsh.h
  1477. Xmailsh.o:    window.h
  1478. Xmakework.o:    defs.h
  1479. Xmakework.o:    path.h
  1480. Xmakework.o:    screen.h
  1481. Xmakework.o:    mailsh.h
  1482. Xmbox.o:    defs.h
  1483. Xmbox.o:    path.h
  1484. Xmbox.o:    pager.h
  1485. Xmbox.o:    screen.h
  1486. Xmbox.o:    mailsh.h
  1487. Xmyalloc.o:    defs.h
  1488. Xnewseqno.o:    defs.h
  1489. Xnewseqno.o:    path.h
  1490. Xnewseqno.o:    dir.h
  1491. Xpager.o:    defs.h
  1492. Xpager.o:    window.h
  1493. Xpager.o:    pager.h
  1494. Xpager.o:    path.h
  1495. Xpager.o:    ascf.h
  1496. Xparams.o:    defs.h
  1497. Xparams.o:    path.h
  1498. Xparams.o:    params.h
  1499. Xpath.o:    defs.h
  1500. Xpath.o:    path.h
  1501. Xpath.o:    status.h
  1502. Xprotomsg.o:    defs.h
  1503. Xprotomsg.o:    params.h
  1504. Xprotomsg.o:    comm.h
  1505. Xprotomsg.o:    logs.h
  1506. Xprotomsg.o:    status.h
  1507. Xrmail.o:    defs.h
  1508. Xrmail.o:    dir.h
  1509. Xrmail.o:    path.h
  1510. Xrmail.o:    status.h
  1511. Xrmtname.o:    defs.h
  1512. Xrmtname.o:    params.h
  1513. Xrmtname.o:    comm.h
  1514. Xrmtname.o:    logs.h
  1515. Xrmtname.o:    status.h
  1516. Xrmtname.o:    path.h
  1517. Xscanwork.o:    defs.h
  1518. Xscanwork.o:    params.h
  1519. Xscanwork.o:    comm.h
  1520. Xscanwork.o:    work.h
  1521. Xscanwork.o:    path.h
  1522. Xscanwork.o:    dir.h
  1523. Xscanwork.o:    logs.h
  1524. Xscreen.o:    defs.h
  1525. Xscreen.o:    screen.h
  1526. Xsendwork.o:    defs.h
  1527. Xsendwork.o:    work.h
  1528. Xsendwork.o:    logs.h
  1529. Xsendwork.o:    status.h
  1530. Xsendwork.o:    params.h
  1531. Xsendwork.o:    comm.h
  1532. Xsetup.o:    defs.h
  1533. Xsetup.o:    path.h
  1534. Xsetup.o:    screen.h
  1535. Xsetup.o:    mailsh.h
  1536. Xsetup.o:    pager.h
  1537. Xsetup.o:    params.h
  1538. Xsetup.o:    status.h
  1539. Xsetup.o:    window.h
  1540. Xsmail.o:    defs.h
  1541. Xsmail.o:    path.h
  1542. Xsmail.o:    status.h
  1543. Xspoolfil.o:    defs.h
  1544. Xspoolfil.o:    path.h
  1545. Xspoolfil.o:    ascf.h
  1546. Xspoolfil.o:    status.h
  1547. Xstartup.o:    defs.h
  1548. Xstartup.o:    params.h
  1549. Xstartup.o:    comm.h
  1550. Xstartup.o:    logs.h
  1551. Xstartup.o:    status.h
  1552. Xstartup.o:    sysdep.h
  1553. Xstr.o:    defs.h
  1554. Xsubmit.o:    defs.h
  1555. Xsubmit.o:    path.h
  1556. Xswitcher.o:    defs.h
  1557. Xswitcher.o:    work.h
  1558. Xswitcher.o:    params.h
  1559. Xswitcher.o:    comm.h
  1560. Xswitcher.o:    logs.h
  1561. Xswitcher.o:    status.h
  1562. Xunalias.o:    defs.h
  1563. Xunalias.o:    hsearch.h
  1564. Xunalias.o:    path.h
  1565. Xunalias.o:    ascf.h
  1566. Xwindow.o:    defs.h
  1567. Xwindow.o:    window.h
  1568. Xxpres.o:    defs.h
  1569. Xxpres.o:    params.h
  1570. Xxpres.o:    comm.h
  1571. Xxpres.o:    status.h
  1572. Xxpres.o:    sysdep.h
  1573. Xxpres.o:    logs.h
  1574. END_OF_makefile.msc
  1575. if test 5643 -ne `wc -c <makefile.msc`; then
  1576.     echo shar: \"makefile.msc\" unpacked with wrong size!
  1577. fi
  1578. # end of overwriting check
  1579. fi
  1580. if test -f rmail.c -a "${1}" != "-c" ; then 
  1581.   echo shar: Will not over-write existing file \"rmail.c\"
  1582. else
  1583. echo shar: Extracting \"rmail.c\" \(6168 characters\)
  1584. sed "s/^X//" >rmail.c <<'END_OF_rmail.c'
  1585. X/*++
  1586. X/* NAME
  1587. X/*      rmail
  1588. X/* SUMMARY
  1589. X/*      extract originator from new mail received by cico
  1590. X/* PROJECT
  1591. X/*      pc-mail
  1592. X/* PACKAGE
  1593. X/*      rmail
  1594. X/* SYNOPSIS
  1595. X/*      rmail
  1596. X/* DESCRIPTION
  1597. X/*      rmail searches for new mail files received by cico and extracts
  1598. X/*    the originator's name, for later use by the mail visual shell.
  1599. X/*
  1600. X/*     Return address formats we understand (in order of preference):
  1601. X/* .nf
  1602. X/*
  1603. X/*    From: address (full_name)    (accept the full_name)
  1604. X/*    From: address            (accept the address)
  1605. X/*    >From address            (take address and keep scanning)
  1606. X/*    From address            (take address and keep scanning)
  1607. X/*
  1608. X/* .fi
  1609. X/*      To avoid tampering, new files will have read-only permission.
  1610. X/*
  1611. X/*      In order to avoid corruption, control-c interrupts are disabled.
  1612. X/* FILES
  1613. X/*      In the spool directory:
  1614. X/*    n<seqno>    received mail message
  1615. X/*    h<seqno>    extracted originator address
  1616. X/* SEE ALSO
  1617. X/*      path(5)         spool directory, file names
  1618. X/*      cico(1)         network process
  1619. X/*      mailsh(1)       visual mail shell
  1620. X/* DIAGNOSTICS
  1621. X/*      Exit status zero when no errors were detected, nonzero in case of file
  1622. X/*      access errors. See status(5) for error codes.
  1623. X/* BUGS
  1624. X/*    Note that the format "From: full_name <address>" is not 
  1625. X/*    recognized. The program will just pick up the first word from
  1626. X/*    full_name.
  1627. X/*
  1628. X/*      Does not really do a good job when parsing the mail headers.
  1629. X/*    At least, not good enough to extract a return path.
  1630. X/* AUTHOR(S)
  1631. X/*      W.Z. Venema
  1632. X/*      Eindhoven University of Technology
  1633. X/*      Department of Mathematics and Computer Science
  1634. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1635. X/* CREATION DATE
  1636. X/*      Tue Mar 31 20:14:11 GMT+1:00 1987
  1637. X/* LAST MODIFICATION
  1638. X/*    Wed Apr  6 00:21:54 MET 1988
  1639. X/* VERSION/RELEASE
  1640. X/*    1.4
  1641. X/*--*/
  1642. X
  1643. X#include <setjmp.h>
  1644. X#include <signal.h>
  1645. X#include <time.h>
  1646. X#include <ctype.h>
  1647. X#include "defs.h"
  1648. X#include "dir.h"
  1649. X#include "path.h"
  1650. X#include "status.h"
  1651. X
  1652. Xextern struct tm *localtime();        /* system functions */
  1653. X
  1654. Xhidden void parse_args();        /* forward declarations */
  1655. Xhidden void newmail();
  1656. Xhidden void extract();
  1657. Xhidden void usage();
  1658. X
  1659. X#define HLEN            20        /* nbr of header lines scanned */
  1660. X
  1661. Xhidden int dflag = 0;            /* debugging option */
  1662. X
  1663. X#define debug    if (dflag) printf
  1664. X
  1665. Xmain(argc,argv)
  1666. Xint argc;
  1667. Xchar **argv;
  1668. X{
  1669. X    signal(SIGINT,SIG_IGN);        /* disable ctrl-c */
  1670. X    parse_args(argc,argv);        /* parse command args */
  1671. X    pathinit();                /* get path info */
  1672. X    umask(0222);            /* make files read-only */
  1673. X    newmail();                /* get headers from new mail */
  1674. X    exit(0);
  1675. X    /* NOTREACHED */
  1676. X}
  1677. X
  1678. X/* parse_args - process command-line arguments */
  1679. X
  1680. Xhidden void parse_args(argc,argv)
  1681. Xint argc;
  1682. Xchar **argv;
  1683. X{
  1684. X    while (--argc && *++argv && **argv == '-') {    /* process options */
  1685. X    switch (*++*argv) {
  1686. X    case 'd':                    /* turn debugging on */
  1687. X        if (--argc == 0)
  1688. X        usage("missing debugging level argument");
  1689. X        sscanf(*++argv,"%d",&dflag);
  1690. X        if (dflag < 0 || dflag > 9)
  1691. X        dflag = 0;
  1692. X        break;
  1693. X    default:                    /* unknown option */
  1694. X        usage(strcons("invalid option: -%c",**argv));
  1695. X        break;
  1696. X    }
  1697. X    }
  1698. X
  1699. X    /* check for extraneous arguments */
  1700. X
  1701. X    if (argc > 0)
  1702. X    usage(strcons("unexpected argument: %s",*argv));
  1703. X}
  1704. X
  1705. X/* scan for new mail that hasn't gotten yet a metafile */
  1706. X
  1707. Xhidden void newmail()
  1708. X{
  1709. X    register int dd;
  1710. X    int pfxlen = sizeof(NEWPFX)-1;
  1711. X    char *f;
  1712. X
  1713. X    debug("directory: \"%s\"\n",maildir);        /* verify */
  1714. X
  1715. X    /*
  1716. X    * Scan the spool directory for newly-arrived mail.
  1717. X    *
  1718. X    * Incoming mail message files have a name of "n<seqno>". 
  1719. X    * The originator name is normally present in files with names
  1720. X    * "h<seqno>" or "o<seqno>".
  1721. X    * The presence of an "o" file implies that the file "n<seqno>"
  1722. X    * has been read by the user. An "h" file means that the user
  1723. X    * has not yet read the message file.
  1724. X    *
  1725. X    * If a message file has no corresponding "h" or "o" file we
  1726. X    * assume it is a new mail message and create an "h" file with 
  1727. X    * the name of the originator.
  1728. X    */
  1729. X
  1730. X    for (dd = opendir(maildir); f = readdir(dd); /* void */) {
  1731. X    int seqno;
  1732. X    debug("rmail: file \"%s\"\n",f);
  1733. X    if (strncmp(f,NEWPFX,pfxlen) == 0 && sscanf(f+pfxlen,"%d",&seqno)) {
  1734. X        if (access(in_meta(seqno),4) == 0) {    /* message already */
  1735. X        /* void */ ;                /* marked as read */
  1736. X        } else if (access(new_meta(seqno),4) == 0) {/* message already */
  1737. X        /* void */ ;                /* marked as unread */
  1738. X        } else {                    /* create meta file */
  1739. X        extract(new_mesg(seqno),new_meta(seqno));
  1740. X        }
  1741. X    }
  1742. X    }
  1743. X    closedir(dd);
  1744. X}
  1745. X
  1746. X/* extract - extract originator info from mail file to meta file */
  1747. X
  1748. Xhidden void extract(mail,meta)
  1749. Xchar *mail;
  1750. Xchar *meta;
  1751. X{
  1752. X    FILE *mesgfp,*metafp;
  1753. X    char line[BUFSIZ];
  1754. X    char from[BUFSIZ];
  1755. X    int n;
  1756. X
  1757. X    debug("-- \"%s\" -> \"%s\"\n",mail,meta);
  1758. X
  1759. X    if ((mesgfp = fopen(mail,"r")) == NULL)    /* cannot open existing file */
  1760. X    exit(E_SYSFAIL);
  1761. X
  1762. X    strcpy(from,"Somewhere");            /* default originator */
  1763. X
  1764. X    /*
  1765. X    * Some mailers generate real headers, separated from the message
  1766. X    * body by an empty line. So we stop when we find an empty line.
  1767. X    * Other mailers have no headers, so we stop after HLEN lines.
  1768. X    * The following algorithm tries to extract the real user name
  1769. X    * if possible, otherwise it takes whatever it can get.
  1770. X    */
  1771. X
  1772. X    for (n = 0; n < HLEN && fgets(line,BUFSIZ,mesgfp) && *line != '\n'; n++) {
  1773. X    if (sscanf(line,"From: %*s ( %[^)] )",from) == 1)
  1774. X        break;
  1775. X    if (sscanf(line,"From: %s",from) == 1)
  1776. X        break;
  1777. X    sscanf(line,"%*[>] From %s",from) || sscanf(line,"From %s",from);
  1778. X    }
  1779. X
  1780. X    /* carefully check all went well */
  1781. X
  1782. X    if (ferror(mesgfp))                /* sorry, read problem */
  1783. X    exit(E_READERR);
  1784. X    if ((metafp = fopen(meta,"w")) == NULL)    /* cannot create metafile */
  1785. X    exit(E_WRITERR);
  1786. X    fprintf(metafp,"%s\n",from);        /* write originator */
  1787. X    if (ferror(metafp)) {
  1788. X    fclose(metafp);                /* ms-dog needs this! */
  1789. X    chmod(meta,0666);            /* sorry, write problem */
  1790. X    unlink(meta);                /* delete metafile */
  1791. X    exit(E_WRITERR);
  1792. X    }
  1793. X    fclose(mesgfp);
  1794. X    fclose(metafp);
  1795. X}
  1796. X
  1797. X/* usage - explain what is wrong */
  1798. X
  1799. Xhidden void usage(str)
  1800. Xchar *str;
  1801. X{
  1802. X    fprintf(stderr,"%s\nusage: rmail [-d debugging_level]\n",str);
  1803. X    exit(2);
  1804. X}
  1805. END_OF_rmail.c
  1806. if test 6168 -ne `wc -c <rmail.c`; then
  1807.     echo shar: \"rmail.c\" unpacked with wrong size!
  1808. fi
  1809. # end of overwriting check
  1810. fi
  1811. if test -f startup.c -a "${1}" != "-c" ; then 
  1812.   echo shar: Will not over-write existing file \"startup.c\"
  1813. else
  1814. echo shar: Extracting \"startup.c\" \(6331 characters\)
  1815. sed "s/^X//" >startup.c <<'END_OF_startup.c'
  1816. X/*++
  1817. X/* NAME
  1818. X/*      startup 3
  1819. X/* SUMMARY
  1820. X/*      startup/terminate network protocol 
  1821. X/* PROJECT
  1822. X/*      pc-mail
  1823. X/* PACKAGE
  1824. X/*      cico
  1825. X/* SYNOPSIS
  1826. X/*      startproto()
  1827. X/*
  1828. X/*      endproto()
  1829. X/* DESCRIPTION
  1830. X/*      startproto() should be called after a successfull login on a remote
  1831. X/*      host. It performs the primary handshake with the other system 
  1832. X/*      (call accepted/locked) and negotiates a communications protocol.
  1833. X/*      It then sets the function pointers Close/Read/Write to the
  1834. X/*      appropriate values. Until endproto() is called, all i/o to the
  1835. X/*      remote host should proceed through the functions pointed to by
  1836. X/*      Read/Write.
  1837. X/*
  1838. X/*      endproto() turns the protocol off, and sends the silly "OO" message
  1839. X/*      to the remote system. It does not disconnect, nor does it change
  1840. X/*      the state of the communications port.
  1841. X/* FUNCTIONS AND MACROS
  1842. X/*      xgetc(), xwrite(), trap()
  1843. X/* DIAGNOSTICS
  1844. X/*      The process of negotiation is shown when debugging is enabled.
  1845. X/*      startproto() and endproto() return 0 in case of success, E_LOST
  1846. X/*      if no response arrived and E_REJECT if the response differed
  1847. X/*      from the expected response.
  1848. X/* BUGS
  1849. X/*      startproto() assumes that the local system is the calling system.
  1850. X/* AUTHOR(S)
  1851. X/*      W.Z. Venema
  1852. X/*      Eindhoven University of Technology
  1853. X/*      Department of Mathematics and Computer Science
  1854. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1855. X/* CREATION DATE
  1856. X/*      Fri Mar 27 13:43:00 GMT+1:00 1987
  1857. X/* LAST MODIFICATION
  1858. X/*    Wed Apr  6 00:22:51 MET 1988
  1859. X/* VERSION/RELEASE
  1860. X/*    1.4
  1861. X/*--*/
  1862. X
  1863. X#include <setjmp.h>
  1864. X#include "defs.h"
  1865. X#include "params.h"
  1866. X#include "comm.h"
  1867. X#include "logs.h"
  1868. X#include "status.h"
  1869. X#include "sysdep.h"
  1870. X
  1871. X/* forward declarations */
  1872. X
  1873. Xhidden char *xpct();                            /* expect a string */
  1874. Xhidden char *send();                            /* send a string */
  1875. X
  1876. X/* the functions that inplement the various protocols */
  1877. X
  1878. Xextern kopen(),kclose(),kread(),kwrite();       /* k protocol */
  1879. Xextern gopen(),gclose(),gread(),gwrite();       /* g protocol */
  1880. X
  1881. Xtypedef struct proto {
  1882. X    char name;                                  /* name of the protocol */
  1883. X    int (*open)();                              /* the open function */
  1884. X    int (*close)();                             /* the close function */
  1885. X    int (*read)();                              /* the read function */
  1886. X    int (*write)();                             /* the write function */
  1887. X};
  1888. X
  1889. X/* the order of protocols is significant! */
  1890. X
  1891. Xhidden struct proto ptable[] = {
  1892. X    'k',        kopen,  kclose, kread,  kwrite, /* try this first */
  1893. X    'g',        gopen,  gclose, gread,  gwrite, /* then this one */
  1894. X    /* add your protocols at the appropriate place */
  1895. X    0,                                          /* terminator! */
  1896. X};
  1897. X
  1898. X/* startproto - do primary handshake, establish protocol and turn it on */
  1899. X
  1900. Xpublic startproto()
  1901. X{
  1902. X    int *savetrap = systrap;
  1903. X    jmp_buf mytrap;
  1904. X    register struct proto *pp;
  1905. X    register char *cp;
  1906. X    int status;
  1907. X
  1908. X    if (status = setjmp(systrap = mytrap)) {    /* get here if expect fails */
  1909. X    systrap = savetrap;
  1910. X    return(status);
  1911. X    }
  1912. X
  1913. X    /* the primary handshake: who are we and is it ok we call right now */
  1914. X
  1915. X    sscanf(xpct("Shere"),"Shere=%s",rmthost);   /* try to get host name */
  1916. X    log("SUCCEEDED (call to %s)",rmthost);
  1917. X    send(strcons("S%s -x%d",LOGIN_NAME,MAX(dflag,1))); /* name + debug level */
  1918. X    xpct("ROK");                                /* we're accepted or rejected */
  1919. X
  1920. X    /* choose a protocol from the list offered by the other side */
  1921. X
  1922. X    for (cp = xpct("P")+1,pp = ptable; pp->name && !index(cp,pp->name); pp++)
  1923. X    /* void */ ;
  1924. X    if (pp->name == 0) {                        /* no common protocol */
  1925. X    send("N");
  1926. X    trap(E_REJECT,"FAILED (no common protocol in \"%s\")",cp);
  1927. X    /* NOTREACHED */
  1928. X    }
  1929. X    send(strcons("U%c",pp->name));        /* my choice of protocol */
  1930. X
  1931. X    /* install protocol */
  1932. X
  1933. X    Close = pp->close;                          /* for endproto() */
  1934. X    Read  = pp->read;
  1935. X    Write = pp->write;
  1936. X    if (pp->open && CALL(pp->open)(ttfd))      /* start up a protocol */
  1937. X    trap(E_LOST,"FAILED (startup)");
  1938. X
  1939. X    log("OK (startup)");
  1940. X    systrap = savetrap;                         /* get here if expect wins */
  1941. X    return(0);
  1942. X}
  1943. X
  1944. X/* endproto - terminate protocol */
  1945. X
  1946. Xpublic endproto()
  1947. X{
  1948. X    int *savetrap = systrap;
  1949. X    jmp_buf mytrap;
  1950. X    int status;
  1951. X
  1952. X    if (status = setjmp(systrap = mytrap)) {    /* get here if expect fails */
  1953. X    systrap = savetrap;
  1954. X    return(status);
  1955. X    }
  1956. X    if (Close)                                  /* check there is one */
  1957. X    CALL(Close)(ttfd);                      /* turn protocol off */
  1958. X    send("OOOOOO");                             /* byebye */
  1959. X    xpct("OO");                                 /* bye */
  1960. X    log("OK (conversation complete)");
  1961. X
  1962. X    systrap = savetrap;                         /* get here if expect wins */
  1963. X    return(0);
  1964. X}
  1965. X
  1966. X/* send - write message to remote host and return pointer to message */
  1967. X
  1968. Xhidden char *send(str)
  1969. Xchar *str;
  1970. X{
  1971. X    xwrite(ttfd,"\020",1);            /* message header */
  1972. X    xwrite(ttfd,str,strlen(str)+1);        /* include trailing null */
  1973. X    debug(4)("send: %S\n",str);
  1974. X    return(str);                /* return the message */
  1975. X}
  1976. X
  1977. X/* xpct - read message from host in "^Pmessage[\0\n]" format; trap on errors */
  1978. X
  1979. Xhidden char *xpct(pat)
  1980. Xchar *pat;
  1981. X{
  1982. X    register int c;
  1983. X    register char *p = msgin;
  1984. X    register int inmsg = 0;
  1985. X
  1986. X    /*
  1987. X    * Keep reading until we time out, the buffer is full, or until a 
  1988. X    * complete message has been received. Consider the link as lost
  1989. X    * in case of time out or buffer overflow. Assume we are rejected
  1990. X    * if the received message differs from what was expected.
  1991. X    */
  1992. X
  1993. X    while (p < msgin+MSGBUF && (c = xgetc()) != EOF) {      
  1994. X    if ((c &= 0177) == '\020') {            /* got start of message */
  1995. X        debug(4)(" got sync\n");
  1996. X        p = msgin;                          /* clear msg buffer */
  1997. X        inmsg = 1;
  1998. X    } else if (inmsg == 0 || (*p++ = (c == '\n' ? 0 : c))) {
  1999. X        debug(4)("%C",c);
  2000. X    } else {                                /* message completed */
  2001. X        debug(4)("\n");
  2002. X        if (strncmp(pat,msgin,strlen(pat))) /* compare prefix only */
  2003. X        break;
  2004. X        return(msgin);
  2005. X    }
  2006. X    }
  2007. X    trap((c == EOF || p >= msgin+MSGBUF ? E_LOST : E_REJECT),
  2008. X    "FAILED (%s)",msgin);
  2009. X    /* NOTREACHED */
  2010. X}
  2011. END_OF_startup.c
  2012. if test 6331 -ne `wc -c <startup.c`; then
  2013.     echo shar: \"startup.c\" unpacked with wrong size!
  2014. fi
  2015. # end of overwriting check
  2016. fi
  2017. echo shar: End of archive 4 \(of 8\).
  2018. cp /dev/null ark4isdone
  2019. MISSING=""
  2020. for I in 1 2 3 4 5 6 7 8 ; do
  2021.     if test ! -f ark${I}isdone ; then
  2022.     MISSING="${MISSING} ${I}"
  2023.     fi
  2024. done
  2025. if test "${MISSING}" = "" ; then
  2026.     echo You have unpacked all 8 archives.
  2027.     rm -f ark[1-9]isdone
  2028. else
  2029.     echo You still need to unpack the following archives:
  2030.     echo "        " ${MISSING}
  2031. fi
  2032. ##  End of shell archive.
  2033. exit 0
  2034. -- 
  2035. uucp:    mcvax!eutrc3!wswietse    | Eindhoven University of Technology
  2036. bitnet:    wswietse@heithe5    | Dept. of Mathematics and Computer Science
  2037. surf:    tuerc5::wswietse    | Eindhoven, The Netherlands.
  2038.